<?php

/**
 * Hyperf 微服务全面功能测试脚本
 * 测试网关调用、直接 RPC 调用、数据库、Redis 等功能
 */

echo "================================================================\n";
echo "🧪 Hyperf 微服务全面功能测试\n";
echo "================================================================\n\n";

// 测试结果统计
$testResults = [
    'total' => 0,
    'passed' => 0,
    'failed' => 0,
    'details' => []
];

function runTest($testName, $testFunction) {
    global $testResults;
    
    $testResults['total']++;
    echo "🔍 测试: $testName\n";
    echo str_repeat("-", 60) . "\n";
    
    try {
        $result = $testFunction();
        if ($result['success']) {
            echo "✅ 通过: " . $result['message'] . "\n";
            $testResults['passed']++;
            $testResults['details'][] = [
                'name' => $testName,
                'status' => 'PASS',
                'message' => $result['message'],
                'data' => $result['data'] ?? null
            ];
        } else {
            echo "❌ 失败: " . $result['message'] . "\n";
            $testResults['failed']++;
            $testResults['details'][] = [
                'name' => $testName,
                'status' => 'FAIL',
                'message' => $result['message'],
                'error' => $result['error'] ?? null
            ];
        }
    } catch (Exception $e) {
        echo "💥 异常: " . $e->getMessage() . "\n";
        $testResults['failed']++;
        $testResults['details'][] = [
            'name' => $testName,
            'status' => 'ERROR',
            'message' => $e->getMessage()
        ];
    }
    
    echo "\n";
}

// 1. 测试网关基础功能
runTest("网关基础信息", function() {
    $response = makeRequest('GET', 'http://localhost:8080/gateway');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['message'])) {
        return [
            'success' => true,
            'message' => "网关信息获取成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "网关信息获取失败",
        'error' => $response
    ];
});

// 2. 测试网关健康检查
runTest("网关健康检查", function() {
    $response = makeRequest('GET', 'http://localhost:8080/gateway/health');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status'])) {
        $status = $data['status'] === 'healthy' ? '健康' : '不健康';
        return [
            'success' => true,
            'message' => "健康检查完成，状态: $status",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "健康检查失败",
        'error' => $response
    ];
});

// 3. 测试网关调用 Notice 服务 RPC
runTest("网关调用 Notice 服务 RPC", function() {
    $response = makeRequest('GET', 'http://localhost:8080/gateway/api/notice/test-rpc');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "网关调用 Notice RPC 成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "网关调用 Notice RPC 失败",
        'error' => $response
    ];
});

// 4. 测试网关调用 Notice 服务数据库操作
runTest("网关调用 Notice 服务数据库操作", function() {
    $response = makeRequest('GET', 'http://localhost:8080/gateway/api/notice/test-db');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "网关调用 Notice 数据库操作成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "网关调用 Notice 数据库操作失败",
        'error' => $response
    ];
});

// 5. 测试网关调用 Notice 服务 Redis 操作
runTest("网关调用 Notice 服务 Redis 操作", function() {
    $response = makeRequest('GET', 'http://localhost:8080/gateway/api/notice/test-redis');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "网关调用 Notice Redis 操作成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "网关调用 Notice Redis 操作失败",
        'error' => $response
    ];
});

// 6. 测试网关调用 Data 服务 RPC
runTest("网关调用 Data 服务 RPC", function() {
    $response = makeRequest('POST', 'http://localhost:8080/gateway/api/data/rpc', '{}');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "网关调用 Data RPC 成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "网关调用 Data RPC 失败",
        'error' => $response
    ];
});

// 7. 测试直接调用 DataService RPC
runTest("直接调用 DataService RPC", function() {
    $rpcData = [
        'jsonrpc' => '2.0',
        'method' => 'data/getCampuses',
        'params' => [['requestId' => 'direct-test-' . uniqid()]],
        'id' => 1
    ];
    
    $response = makeRequest('POST', 'http://localhost:9509/data/getCampuses', json_encode($rpcData));
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['result'])) {
        return [
            'success' => true,
            'message' => "直接调用 DataService RPC 成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "直接调用 DataService RPC 失败",
        'error' => $response
    ];
});

// 8. 测试直接调用 NoticeService RPC
runTest("直接调用 NoticeService RPC", function() {
    $rpcData = [
        'jsonrpc' => '2.0',
        'method' => 'notice/getNotice2Data',
        'params' => [],
        'id' => 2
    ];
    
    $response = makeRequest('POST', 'http://localhost:9502/notice/getNotice2Data', json_encode($rpcData));
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['result'])) {
        return [
            'success' => true,
            'message' => "直接调用 NoticeService RPC 成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "直接调用 NoticeService RPC 失败",
        'error' => $response
    ];
});

// 9. 测试直接访问 Notice 服务 HTTP 接口
runTest("直接访问 Notice 服务 HTTP 接口", function() {
    $response = makeRequest('GET', 'http://localhost:9501/test-rpc');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "直接访问 Notice HTTP 接口成功",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "直接访问 Notice HTTP 接口失败",
        'error' => $response
    ];
});

// 10. 测试 Nacos 服务注册
runTest("Nacos 服务注册检查", function() {
    $response = makeRequest('GET', 'http://localhost:8848/nacos/v1/ns/instance/list?serviceName=DataService&namespaceId=public&groupName=DEFAULT_GROUP');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['hosts']) && count($data['hosts']) > 0) {
        $serviceCount = count($data['hosts']);
        return [
            'success' => true,
            'message' => "DataService 已注册到 Nacos，实例数: $serviceCount",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "DataService 未在 Nacos 中注册",
        'error' => $response
    ];
});

// 11. 测试 Notice 服务在 Nacos 中的注册
runTest("Notice 服务在 Nacos 中的注册", function() {
    $response = makeRequest('GET', 'http://localhost:8848/nacos/v1/ns/instance/list?serviceName=NoticeService&namespaceId=public&groupName=DEFAULT_GROUP');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['hosts']) && count($data['hosts']) > 0) {
        $serviceCount = count($data['hosts']);
        return [
            'success' => true,
            'message' => "NoticeService 已注册到 Nacos，实例数: $serviceCount",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "NoticeService 未在 Nacos 中注册",
        'error' => $response
    ];
});

// 12. 测试服务间 RPC 调用（Notice 调用 Data）
runTest("服务间 RPC 调用（Notice 调用 Data）", function() {
    $response = makeRequest('GET', 'http://localhost:9501/test-rpc');
    $data = json_decode($response['body'], true);
    
    if ($response['http_code'] === 200 && isset($data['status']) && $data['status'] === 'success') {
        return [
            'success' => true,
            'message' => "Notice 服务成功调用 Data 服务 RPC",
            'data' => $data
        ];
    }
    
    return [
        'success' => false,
        'message' => "Notice 服务调用 Data 服务 RPC 失败",
        'error' => $response
    ];
});

// 辅助函数：发送 HTTP 请求
function makeRequest($method, $url, $data = null) {
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
    
    if ($method === 'POST') {
        curl_setopt($ch, CURLOPT_POST, true);
        if ($data) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
            curl_setopt($ch, CURLOPT_HTTPHEADER, [
                'Content-Type: application/json',
            ]);
        }
    }
    
    $body = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $error = curl_error($ch);
    curl_close($ch);
    
    return [
        'http_code' => $httpCode,
        'body' => $body,
        'error' => $error
    ];
}

// 输出测试结果总结
echo "================================================================\n";
echo "📊 测试结果总结\n";
echo "================================================================\n";
echo "总测试数: {$testResults['total']}\n";
echo "通过: {$testResults['passed']} ✅\n";
echo "失败: {$testResults['failed']} ❌\n";
echo "成功率: " . round(($testResults['passed'] / $testResults['total']) * 100, 2) . "%\n\n";

if ($testResults['failed'] > 0) {
    echo "❌ 失败的测试:\n";
    foreach ($testResults['details'] as $test) {
        if ($test['status'] !== 'PASS') {
            echo "  - {$test['name']}: {$test['message']}\n";
        }
    }
    echo "\n";
}

echo "✅ 通过的测试:\n";
foreach ($testResults['details'] as $test) {
    if ($test['status'] === 'PASS') {
        echo "  - {$test['name']}: {$test['message']}\n";
    }
}

echo "\n================================================================\n";
echo "🎯 测试完成！\n";
echo "================================================================\n";

// 保存详细结果到文件
file_put_contents('test_results.json', json_encode($testResults, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
echo "📄 详细测试结果已保存到: test_results.json\n";

?>
